﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Text;
using System.Windows.Forms;

namespace Firefly.Forms {
    public partial class ClientForm : Form {

        public WorldCache WorldCache { get; private set; }
        public event EventHandler OnActivity;
        public delegate void UpdateToolStripCallback();
        public delegate void FlashWindowCallback();

        public ClientForm() {
            InitializeComponent();
            WorldCache = new WorldCache(tabControl1);

            // Register events
            WorldCache.OnWorldCreated += new EventHandler(delegate(object o, EventArgs e) {
                World w = (World)o;

                w.OnActivity += new EventHandler(delegate(object s, EventArgs ea) { // Window and table flashing on activity
                    if (OnActivity != null)
                        OnActivity.Invoke(s, ea);
                });
                w.OnConnect += new EventHandler(delegate(object s, EventArgs ea) { // Enable/Disable buttons for toolbar
                    UpdateToolStrip();
                });
                w.OnDisconnect += new EventHandler(delegate(object s, EventArgs ea) { // Enable/Disable buttons for toolbar
                    UpdateToolStrip();
                });
            });
        }

        protected override void OnClosing(CancelEventArgs e) {
            bool openWorld = false;
            foreach (World w in WorldCache.Values) 
                if (w.Connection.ConnectionStatus())
                    openWorld = true;

            if (openWorld) {
                if (MessageBox.Show("Quitting now will result in the disconnection of all connected worlds. Are you sure you want to do this?",
                    "Verify Disconnection", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) {
                    base.OnClosing(e);
                    Program.QuitProgram();
                }
            } else {
                base.OnClosing(e);
                Program.QuitProgram();
            }
        }

        private void UpdateToolStrip() {
            if (tabControl1.InvokeRequired) {
                this.Invoke(new UpdateToolStripCallback(UpdateToolStrip));
            } else {
                World w = WorldCache[tabControl1.SelectedTab.Text];
                if (w.Connection.Client.Connected) {
                    toolStripButtonConnect.Enabled = false;
                    toolStripButtonDisconnect.Enabled = true;
                } else {
                    toolStripButtonConnect.Enabled = true;
                    toolStripButtonDisconnect.Enabled = false;
                }
                // Always enabled regardless of connection, just as long as a world is connected/disconnected.
                toolStripButtonWorldEdit.Enabled = true;
                toolStripButtonWorldDelete.Enabled = true;
            }
        }

        protected void tabControl1_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
            World w = (World)tabControl1.Controls[tabControl1.SelectedIndex];
            // Toolstrip buttons
            toolStripButtonWorldEdit.Enabled = true;
            toolStripButtonWorldDelete.Enabled = true;
            if (w.Connection.Client.Connected) {
                toolStripButtonConnect.Enabled = false;
                toolStripButtonDisconnect.Enabled = true;
            } else {
                toolStripButtonConnect.Enabled = true;
                toolStripButtonDisconnect.Enabled = false;
            }

        }

        private void toolStripButtonWorldManager_Click(object sender, EventArgs e) {
            Program.WindowManager.OpenForm("World Selector");
        }

        private void toolStripButtonWorldAdd_Click(object sender, EventArgs e) {
            WorldEditorForm wef = (WorldEditorForm)Program.WindowManager.Forms["World Editor"];
            wef.OpenWorld();
            Program.WindowManager.OpenForm("World Editor");
        }

        private void toolStripButtonDisconnect_Click(object sender, EventArgs e) {
            World w = WorldCache[tabControl1.SelectedTab.Text];

            w.Connection.Disconnect();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
            Program.WindowManager.OpenForm("Client Settings");
        }

        public void Flash() {
            if (this.InvokeRequired) {
                this.Invoke(new FlashWindowCallback(Flash));
            } else {
                Firefly.Controls.FlashWindow.Flash(this);
            }
        }
    }

    public class WorldCache : Dictionary<string, World> {

        public List<World> WorldIDList { get; private set; }

        public event EventHandler OnWorldCreated;

        public WorldCache(TabControl container) {
            this.mContainer = container;
            this.WorldIDList = new List<World>();
        }

        public void Add(string name, string server, int port) {
            World w = new World(name, server, port);
            AddWorld(w);
        }

        public void Add(string name) {
            // Load existing world data.
            World w = new World(name);
            AddWorld(w);
        }

        private void AddWorld(World w) {
            if (OnWorldCreated != null)
                OnWorldCreated.Invoke(w, null);
            WorldIDList.Add(w);
            base.Add(w.Config.WorldName, w);

            mContainer.Controls.Add(w);
            mContainer.SelectedTab = w;
            // Connect it.
            w.InitiateConnection();
        }

        private TabControl mContainer;
    }
}
